`timescale 1ns/1ps
`default_nettype none

/* NOTE:
*  - LED输出模块
*/

module pixel_display_top
    #(
    parameter   DW  = 96,
    parameter   DP  = 96
    )
    (
    // system signal
    input  wire         I_sclk,  // 125M
    input  wire         I_sdram_clk, // 150M
    input  wire         I_rst_n,
    // frame
    input  wire         I_fake_frame_start,
    input  wire         I_frame_sync,
    // ext setting
    input  wire         I_ext_lock_output,
    input  wire         I_ext_black_screen,
    // config
    input  wire         I_cfg_output_enable, // 输出使能
    input  wire [1:0]   I_cfg_scan_mode,
    input  wire [7:0]   I_cfg_clock_low,     // 时钟低电平时钟数
    input  wire [7:0]   I_cfg_clock_cycle,   // 时钟整周期时钟数
    input  wire [7:0]   I_cfg_clock_phase,   // 时钟相位
    input  wire [7:0]   I_cfg_clock_phase_2, // 时钟相位2
    input  wire         I_cfg_data_polarity, // 数据极性
    input  wire [9:0]   I_cfg_scan_pixel,    // 一扫的像素数量（不包含虚点）
    input  wire [9:0]   I_cfg_scan_length,   // 一扫的像素数量（包含虚点）
    input  wire [5:0]   I_cfg_scan_max,      // 最大扫描id
    input  wire [4:0]   I_cfg_port_max,      // 最大端口id
    input  wire [7:0]   I_cfg_line_pos,      // 换行位置
    input  wire [7:0]   I_cfg_load_width,    // load信号宽度 (>=2)
    input  wire [7:0]   I_cfg_oe_pre_width,  // 切换非整周期时oe提前拉低宽度
    input  wire         I_cfg_oe_polarity,   // oe极性
    input  wire [15:0]  I_cfg_chain_cycle,   // 串移时钟数
    input  wire         I_cfg_fps_sync_en,   // 帧率同步使能
    input  wire [15:0]  I_cfg_min_chain,     // 最小串移周期数
    input  wire [11:0]  I_cfg_chain_num,     // 显示周期串移数
    input  wire [5:0]   I_cfg_color_sel,     // RGB选择
    input  wire [1:0]   I_cfg_box_dir,       // 箱体方向
    input  wire [7:0]   I_cfg_vport_num,     // 虚拟数据组数
    input  wire [31:0]  I_cfg_vport_mask,    // 虚拟数据组中有效组标识
    input  wire [15:0]  I_cfg_decode_param0,  // 译码参数0
    input  wire [15:0]  I_cfg_decode_param1,  // 译码参数1
    input  wire [15:0]  I_cfg_deghost_ctrl_dly, // 消影信号延迟
    input  wire [15:0]  I_cfg_deghost_ctrl_len, // 消影信号长度
    input  wire [2:0]   I_cfg_decode_type,   // 译码方式
    input  wire [7:0]   I_cfg_chip_type,     // 芯片类型
    input  wire [255:0] I_cfg_pwm_setting,   // pwm芯片设置
    input  wire         I_cfg_force_en,      // 强制读出的第几bit为1，其余bit为0
    input  wire [4:0]   I_cfg_force_bit,     // 0:全为0; 1:只bit0为1; 2:只bit1为1; ...
    input  wire [3:0]   I_cfg_gamma_bit,
    input  wire [3:0]   I_cfg_hub_brd_type,  // G602使用的Hub板类型
    // cycle info
    output wire         O_cycle_info_rden,
    output wire [8:0]   O_cycle_info_addr,
    input  wire [15:0]  I_cycle_info_q,
    // scan map
    output wire         O_scan_map_rden,
    output wire [5:0]   O_scan_map_addr,
    input  wire [5:0]   I_scan_map_q,
    // port map
    output wire         O_port_map_rden,
    output wire [7:0]   O_port_map_addr,
    input  wire [4:0]   I_port_map_q,
    // column addr table
    output wire         O_col_addr_req,
    output wire [8:0]   O_col_addr_index,
    input  wire [8:0]   I_col_addr_data,
    // frame id
    output wire         O_frame_req,
    input  wire [1:0]   I_frame_id,
    // sdram mux
    input  wire         I_sdram_ready,
    output wire         O_read_sdram_req,
    input  wire         I_read_sdram_ack,
    input  wire         I_read_sdram_irq,
    output wire         O_read_sdram_cs_n,
    output wire         O_read_sdram_ras_n,
    output wire         O_read_sdram_cas_n,
    output wire         O_read_sdram_we_n,
    output wire [1:0]   O_read_sdram_ba,
    output wire [10:0]  O_read_sdram_addr,
    output wire [31:0]  O_read_sdram_dq_out,
    input  wire [31:0]  I_read_sdram_dq_in,
    output wire         O_read_sdram_dq_oe,
    output wire [3:0]   O_read_sdram_dqm,
    // led signal
    output wire         O_oe_out,
    output wire         O_load_out,
    output wire         O_deghost_ctrl,
    output wire [4:0]   O_scan_out,
    output wire         O_clock_out,
    output wire [DP-1:0] O_data_out
);
//------------------------Parameter----------------------
// chip type
localparam
    CHIP_GENERAL  = 0,
    CHIP_ICN2038S = 2; // 同时兼容ICN2028,SM16207S

//------------------------Local signal-------------------
// read request
wire        read_req;         // 读请求
wire        read_busy;        // 读忙碌
wire [1:0]  read_sdram_sel;   // 读取SDRAM分块地址
wire [3:0]  read_bit_sel;     // 读取的bit选择
wire [5:0]  read_scan_id;     // 读取的scan id
wire [4:0]  read_port_max;    // 读取的最大port id
wire [9:0]  read_pixel_count; // 读取的像素数，总是8的倍数，最多512
wire        read_buf_index;   // 存放到RAM的id

// display buf
wire        ram_wclk;
wire [7:0]  ram_wren;
wire [8:0]  ram_waddr;
wire [23:0] ram_wdata;

wire        buf_frm_start;
wire        buf_sel;
wire        buf_vld;
wire [4:0]  buf_port;
wire        buf_port_end;
wire [23:0] buf_data;

wire        ram_rclk;
wire        ram_rden;
wire [9:0]  ram_raddr;
wire [DW-1:0] ram_rdata;

// display control
wire        display_reset;       // 强制重新开始串移
wire        display_end;         // 每个显示周期结束标识
wire        display_ready;         // 每个显示周期结束标识
wire        display_chain_end;   // 每个串移周期结束标识
wire        display_param_en;    // 更新参数
wire [15:0] display_chain_cycle; // 串移时钟数
wire [15:0] display_extra_cycle; // 额外的串移时钟数
wire        real_display_reset;

// scan decoder
wire        scan_prep;
wire        scan_commit;
wire [4:0]  scan_num;
wire        deghost_ctrl;
wire [4:0]  scan_out;

// led signal
wire        oe_out;

reg         oe_out0;
reg         load_out0;
reg         deghost_ctrl0;
reg  [4:0]  scan_out0;
reg         clock_out0;
reg  [DW-1:0] data_out0;

// general
wire        chip0_enable;
wire        chip0_frame_req;
wire        chip0_read_req;
wire [1:0]  chip0_read_sdram_sel;
wire [3:0]  chip0_read_bit_sel;
wire [4:0]  chip0_read_scan_id;
wire [4:0]  chip0_read_port_max;
wire [9:0]  chip0_read_pixel_count;
wire        chip0_read_buf_index;
wire        chip0_ram_rden;
wire [9:0]  chip0_ram_addr;
wire        chip0_scan_prep;
wire        chip0_scan_commit;
wire [4:0]  chip0_scan_num;
wire        chip0_oe_out;
wire        chip0_load_out;
wire        chip0_clock_out;
wire [DW-1:0] chip0_data_out;
wire        chip0_display_end;
wire        chip0_display_ready;
wire        chip0_display_chain_end;
wire        chip0_cycle_info_rden;
wire [8:0]  chip0_cycle_info_addr;
wire        chip0_col_addr_req;
wire [8:0]  chip0_col_addr_index;

// icn2038s
wire        chip1_enable;
wire        chip1_frame_req;
wire        chip1_read_req;
wire [1:0]  chip1_read_sdram_sel;
wire [3:0]  chip1_read_bit_sel;
wire [4:0]  chip1_read_scan_id;
wire [4:0]  chip1_read_port_max;
wire [9:0]  chip1_read_pixel_count;
wire        chip1_read_buf_index;
wire        chip1_ram_rden;
wire [9:0]  chip1_ram_addr;
wire        chip1_scan_prep;
wire        chip1_scan_commit;
wire [4:0]  chip1_scan_num;
wire        chip1_oe_out;
wire        chip1_load_out;
wire        chip1_clock_out;
wire [DW-1:0] chip1_data_out;
wire        chip1_display_end;
wire        chip1_display_ready;
wire        chip1_display_chain_end;
wire        chip1_cycle_info_rden;
wire [8:0]  chip1_cycle_info_addr;
wire        chip1_col_addr_req;
wire [8:0]  chip1_col_addr_index;

reg         fake_frame_en;

//------------------------Instantiation------------------
// cxy_pixel_reader
cxy_pixel_reader reader (/*{{{*/
    .I_sclk             ( I_sclk ),
    .I_sdram_clk        ( I_sdram_clk ),
    .I_rst_n            ( I_rst_n ),

    .I_cfg_scan_mode    ( I_cfg_scan_mode ),
    .I_cfg_color_sel    ( I_cfg_color_sel ),
    .I_cfg_box_dir      ( /*I_cfg_box_dir*/0 ),
    .I_cfg_vport_num    ( I_cfg_vport_num ),
    .I_cfg_vport_mask   ( I_cfg_vport_mask ),
    .I_cfg_force_en     ( I_cfg_force_en ),
    .I_cfg_force_bit    ( I_cfg_force_bit ),

    .I_read_req         ( read_req ),
    .O_read_busy        ( read_busy ),
    .I_read_sdram_sel   ( read_sdram_sel ),
    .I_read_bit_sel     ( read_bit_sel ),
    .I_read_scan_id     ( read_scan_id ),
    .I_read_port_max    ( read_port_max ),
    .I_read_pixel_count ( read_pixel_count ),
    .I_read_buf_index   ( read_buf_index ),

    .O_scan_map_rden    ( O_scan_map_rden ),
    .O_scan_map_addr    ( O_scan_map_addr ),
    .I_scan_map_q       ( I_scan_map_q ),

    .O_port_map_rden    ( O_port_map_rden ),
    .O_port_map_addr    ( O_port_map_addr ),
    .I_port_map_q       ( I_port_map_q ),

    .O_ram_wclk         ( ram_wclk ),
    .O_ram_wren         ( ram_wren ),
    .O_ram_addr         ( ram_waddr ),
    .O_ram_data         ( ram_wdata ),

    .O_buf_frm_start    ( buf_frm_start     ),
    .O_buf_sel          ( buf_sel           ),
    .O_buf_vld          ( buf_vld           ),
    .O_buf_port         ( buf_port          ),
    .O_buf_port_end     ( buf_port_end      ),
    .O_buf_data         ( buf_data          ),

    .O_mux_req          ( O_read_sdram_req ),
    .I_mux_ack          ( I_read_sdram_ack ),
    .O_mux_cs_n         ( O_read_sdram_cs_n ),
    .O_mux_ras_n        ( O_read_sdram_ras_n ),
    .O_mux_cas_n        ( O_read_sdram_cas_n ),
    .O_mux_we_n         ( O_read_sdram_we_n ),
    .O_mux_ba           ( O_read_sdram_ba ),
    .O_mux_addr         ( O_read_sdram_addr ),
    .O_mux_dq_out       ( O_read_sdram_dq_out ),
    .I_mux_dq_in        ( I_read_sdram_dq_in ),
    .O_mux_dq_oe        ( O_read_sdram_dq_oe ),
    .O_mux_dqm          ( O_read_sdram_dqm )
);/*}}}*/

// cxy_pixel_display_buf
cxy_pixel_display_buf /*{{{*/
    #(
    .DW                 (DW      )
    )
  db (
    .I_wclk             ( ram_wclk ),
    .I_wren             ( ram_wren ),
    .I_waddr            ( ram_waddr ),
    .I_wdata            ( ram_wdata ),

    .I_rclk             ( ram_rclk ),
    .I_rden             ( ram_rden ),
    .I_raddr            ( ram_raddr ),
    .O_rdata            ( ram_rdata )
);/*}}}*/

// cxy_pixel_display_buf_2
//cxy_pixel_display_buf_2 db (/*{{{*/
//    .I_sdram_clk        (I_sdram_clk        ),
//    .I_rst_n            (I_rst_n            ),
//
//    .I_buf_frm_start    (buf_frm_start      ),
//    .I_buf_sel          (buf_sel            ),
//    .I_buf_vld          (buf_vld            ),
//    .I_buf_port         (buf_port           ),
//    .I_buf_port_end     (buf_port_end       ),
//    .I_buf_data         (buf_data           ),
//
//    .I_rclk             (ram_rclk           ),
//    .I_rden             (ram_rden           ),
//    .I_raddr            (ram_raddr          ),
//    .O_rdata            (ram_rdata          )
//    );/*}}}*/

// pixel_display_general
pixel_display_general /*{{{*/
    #(
    .DW                    (DW      )
    )
  general (
    .I_sclk                ( I_sclk ),
    .I_rst_n               ( I_rst_n ),
  //.I_frame_sync          ( I_frame_sync ),
    .I_frame_sync          ( I_frame_sync | I_fake_frame_start ),
    .I_enable              ( chip0_enable ),
    .I_ext_lock_output     ( I_ext_lock_output ),
    .I_ext_black_screen    ( I_ext_black_screen ),
    .I_cfg_scan_pixel      ( I_cfg_scan_pixel ),
    .I_cfg_gamma_bit       ( I_cfg_gamma_bit ),
    .I_cfg_scan_length     ( I_cfg_scan_length ),
    .I_cfg_scan_max        ( I_cfg_scan_max ),
    .I_cfg_port_max        ( I_cfg_port_max ),
    .I_cfg_line_pos        ( I_cfg_line_pos ),
    .I_cfg_load_width      ( I_cfg_load_width ),
    .I_cfg_oe_pre_width    ( I_cfg_oe_pre_width ),
    .I_cfg_clock_low       ( I_cfg_clock_low ),
    .I_cfg_clock_cycle     ( I_cfg_clock_cycle ),
    .I_cfg_clock_phase     ( I_cfg_clock_phase ),
    .I_cfg_data_polarity   ( I_cfg_data_polarity ),
    .I_cfg_pwm_setting     ( I_cfg_pwm_setting ),
    .O_cycle_info_rden     ( chip0_cycle_info_rden ),
    .O_cycle_info_addr     ( chip0_cycle_info_addr ),
    .I_cycle_info_q        ( I_cycle_info_q ),
    .O_frame_req           ( chip0_frame_req ),
    .I_frame_id            ( I_frame_id ),
    .I_display_reset       ( real_display_reset ),
    .O_display_end         ( chip0_display_end ),
    .O_display_ready       ( chip0_display_ready ),
    .O_display_chain_end   ( chip0_display_chain_end ),
    .I_display_param_en    ( display_param_en ),
    .I_display_chain_cycle ( display_chain_cycle ),
    .I_display_extra_cycle ( display_extra_cycle ),
    .O_read_req            ( chip0_read_req ),
    .I_read_busy           ( read_busy ),
    .O_read_buf_sel        ( chip0_read_sdram_sel ),
    .O_read_bit_sel        ( chip0_read_bit_sel ),
    .O_read_scan_id        ( chip0_read_scan_id ),
    .O_read_port_max       ( chip0_read_port_max ),
    .O_read_pixel_count    ( chip0_read_pixel_count ),
    .O_read_buf_index      ( chip0_read_buf_index ),
    .O_scan_prep           ( chip0_scan_prep ),
    .O_scan_commit         ( chip0_scan_commit ),
    .O_scan_num            ( chip0_scan_num ),
    .O_col_addr_req        ( chip0_col_addr_req ),
    .O_col_addr_index      ( chip0_col_addr_index ),
    .I_col_addr_data       ( I_col_addr_data ),
    .O_data_ram_rden       ( chip0_ram_rden ),
    .O_data_ram_addr       ( chip0_ram_addr ),
    .I_data_ram_q          ( ram_rdata ),
    .O_oe_out              ( chip0_oe_out ),
    .O_load_out            ( chip0_load_out ),
    .O_clock_out           ( chip0_clock_out ),
    .O_data_out            ( chip0_data_out )
);/*}}}*/

// pixel_display_ex
pixel_display_ex /*{{{*/
    #(
    .DW                    (DW      )
    )
  double_latch (
    .I_sclk                ( I_sclk ),
    .I_rst_n               ( I_rst_n ),
    .I_enable              ( chip1_enable ),
    .I_ext_lock_output     ( I_ext_lock_output ),
    .I_ext_black_screen    ( I_ext_black_screen ),
    .I_cfg_scan_pixel      ( I_cfg_scan_pixel ),
    .I_cfg_scan_length     ( I_cfg_scan_length ),
    .I_cfg_scan_max        ( I_cfg_scan_max ),
    .I_cfg_port_max        ( I_cfg_port_max ),
    .I_cfg_clock_low       ( I_cfg_clock_low ),
    .I_cfg_clock_cycle     ( I_cfg_clock_cycle ),
    .I_cfg_clock_phase     ( I_cfg_clock_phase ),
    .I_cfg_data_polarity   ( I_cfg_data_polarity ),
    .I_cfg_pwm_setting     ( I_cfg_pwm_setting ),
    .O_cycle_info_rden     ( chip1_cycle_info_rden ),
    .O_cycle_info_addr     ( chip1_cycle_info_addr ),
    .I_cycle_info_q        ( I_cycle_info_q ),
    .O_frame_req           ( chip1_frame_req ),
    .I_frame_id            ( I_frame_id ),
    .I_display_reset       ( real_display_reset ),
    .O_display_end         ( chip1_display_end ),
    .O_display_ready       ( chip1_display_ready ),
    .O_display_chain_end   ( chip1_display_chain_end ),
    .I_display_param_en    ( display_param_en ),
    .I_display_chain_cycle ( display_chain_cycle ),
    .I_display_extra_cycle ( display_extra_cycle ),
    .O_read_req            ( chip1_read_req ),
    .I_read_busy           ( read_busy ),
    .O_read_buf_sel        ( chip1_read_sdram_sel ),
    .O_read_bit_sel        ( chip1_read_bit_sel ),
    .O_read_scan_id        ( chip1_read_scan_id ),
    .O_read_port_max       ( chip1_read_port_max ),
    .O_read_pixel_count    ( chip1_read_pixel_count ),
    .O_read_buf_index      ( chip1_read_buf_index ),
    .O_scan_prep           ( chip1_scan_prep ),
    .O_scan_commit         ( chip1_scan_commit ),
    .O_scan_num            ( chip1_scan_num ),
    .O_col_addr_req        ( chip1_col_addr_req ),
    .O_col_addr_index      ( chip1_col_addr_index ),
    .I_col_addr_data       ( I_col_addr_data ),
    .O_data_ram_rden       ( chip1_ram_rden ),
    .O_data_ram_addr       ( chip1_ram_addr ),
    .I_data_ram_q          ( ram_rdata ),
    .O_oe_out              ( chip1_oe_out ),
    .O_load_out            ( chip1_load_out ),
    .O_clock_out           ( chip1_clock_out ),
    .O_data_out            ( chip1_data_out )
);/*}}}*/

// cxy_scan_decoder
cxy_scan_decoder sd (/*{{{*/
    .I_sclk                 (I_sclk                 ),
    .I_rst_n                (I_rst_n                ),
    .I_cfg_scan_max         (I_cfg_scan_max         ),
    .I_cfg_decode_type      (I_cfg_decode_type      ),
    .I_cfg_decode_param0    (I_cfg_decode_param0    ),
    .I_cfg_decode_param1    (I_cfg_decode_param1    ),
    .I_cfg_deghost_ctrl_dly (I_cfg_deghost_ctrl_dly ),
    .I_cfg_deghost_ctrl_len (I_cfg_deghost_ctrl_len ),
    .I_scan_prep            (scan_prep              ),
    .I_scan_num             (scan_num               ),
    .I_scan_commit          (scan_commit            ),
    .O_deghost_ctrl         (deghost_ctrl           ),
    .O_scan_out             (scan_out               )
);/*}}}*/

// fps_sync
fps_sync #(/*{{{*/
    .MAX_PHASE_ERROR       ( 2000 )
) sync (
    .I_sclk                ( I_sclk ),
    .I_rst_n               ( I_rst_n ),
    .I_cfg_output_enable   ( I_cfg_output_enable ),
    .I_cfg_fps_sync_en     ( I_cfg_fps_sync_en ),
    .I_cfg_chain_cycle     ( I_cfg_chain_cycle ),
    .I_cfg_min_chain       ( I_cfg_min_chain ),
    .I_cfg_chain_num       ( I_cfg_chain_num ),
  //.I_frame_sync          ( I_frame_sync ),
    .I_frame_sync          ( I_frame_sync | I_fake_frame_start ),
    .O_display_reset       ( display_reset ),
    .I_display_end         ( display_end ),
    .I_display_ready       ( display_ready ),
    .I_display_chain_end   ( display_chain_end ),
    .O_display_param_en    ( display_param_en ),
    .O_display_chain_cycle ( display_chain_cycle ),
    .O_display_extra_cycle ( display_extra_cycle )
);/*}}}*/

//------------------------Body---------------------------
//{{{+++++++++++++++++++++fsp_sync+++++++++++++++++++++++
assign real_display_reset = ~I_cfg_output_enable
                          | ~I_sdram_ready
                          | display_reset;

// NOTE: 不同芯片控制模块信号进行或运算
assign display_end       = chip0_display_end
                         | chip1_display_end;
assign display_chain_end = chip0_display_chain_end
                         | chip1_display_chain_end;
assign display_ready     = chip0_display_ready
                         | chip1_display_ready;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++read request+++++++++++++++++++
// NOTE: 不同芯片控制模块信号进行或运算
assign read_req         = chip0_read_req
                        | chip1_read_req;
assign read_sdram_sel   = chip0_read_sdram_sel
                        | chip1_read_sdram_sel;
assign read_bit_sel     = chip0_read_bit_sel
                        | chip1_read_bit_sel;
assign read_scan_id     = chip0_read_scan_id
                        | chip1_read_scan_id;
assign read_port_max    = chip0_read_port_max
                        | chip1_read_port_max;
assign read_pixel_count = chip0_read_pixel_count
                        | chip1_read_pixel_count;
assign read_buf_index   = chip0_read_buf_index
                        | chip1_read_buf_index;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++display buf++++++++++++++++++++
// NOTE: 不同芯片控制模块信号进行或运算
assign ram_rclk  = I_sclk;
assign ram_rden  = chip0_ram_rden
                 | chip1_ram_rden;
assign ram_raddr = chip0_ram_addr
                 | chip1_ram_addr;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++scan decoder+++++++++++++++++++
// NOTE: 不同芯片控制模块信号进行或运算
assign scan_prep   = chip0_scan_prep
                   | chip1_scan_prep;
assign scan_commit = chip0_scan_commit
                   | chip1_scan_commit;
assign scan_num    = chip0_scan_num
                   | chip1_scan_num;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++frame id+++++++++++++++++++++++
// NOTE: 不同芯片控制模块信号进行或运算
assign O_frame_req = fake_frame_en ? 1'b0 :
                     (chip0_frame_req
                    | chip1_frame_req);

//fake_frame_en
always@(posedge I_sclk or negedge I_rst_n)
    if(!I_rst_n)
        fake_frame_en <= 'b0;
    else if(I_frame_sync)
        fake_frame_en <= 'b0;
    else if(I_fake_frame_start)
        fake_frame_en <= 1'b1;

//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++led signal+++++++++++++++++++++
assign O_oe_out       = oe_out0;
assign O_load_out     = load_out0;
assign O_deghost_ctrl = deghost_ctrl0;
assign O_scan_out     = scan_out0;
assign O_clock_out    = clock_out0;
assign O_data_out     = data_out0;

// NOTE: 不同芯片控制模块信号进行或运算
always@(posedge I_sclk)
    begin
        deghost_ctrl0 <= deghost_ctrl;
        scan_out0     <= scan_out;
        oe_out0       <= (I_cfg_oe_polarity==1) ? oe_out : ~oe_out;
        load_out0     <= chip0_load_out  | chip1_load_out;
        clock_out0    <= chip0_clock_out | chip1_clock_out;
        data_out0     <= chip0_data_out  | chip1_data_out;
    end

//oe_out
assign oe_out = chip0_oe_out | chip1_oe_out;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++cycle info+++++++++++++++++++++
// NOTE: 不同芯片控制模块信号进行或运算
assign O_cycle_info_rden = chip0_cycle_info_rden
                         | chip1_cycle_info_rden;
assign O_cycle_info_addr = chip0_cycle_info_addr
                         | chip1_cycle_info_addr;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++column addr table++++++++++++++
// NOTE: 不同芯片控制模块信号进行或运算
assign O_col_addr_req   = chip0_col_addr_req
                        | chip1_col_addr_req;
assign O_col_addr_index = chip0_col_addr_index
                        | chip1_col_addr_index;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++chip control+++++++++++++++++++
assign chip0_enable = (I_cfg_output_enable && I_cfg_chip_type == CHIP_GENERAL);
assign chip1_enable = (I_cfg_output_enable && I_cfg_chip_type == CHIP_ICN2038S);
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

endmodule

`default_nettype wire

// vim:set ts=4 sw=4 et fenc=utf-8 fdm=marker:
